package top.rainbowecho.gateway.security.authentication.mail;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.SecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.DefaultSecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.stereotype.Component;
import top.rainbowecho.gateway.security.property.SecurityProperties;

/**
 * @author rainbow
 * @since 2019/12/15 10:49
 */
@Component
public class MailAuthenticationConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {
    private AuthenticationSuccessHandler authenticationSuccessHandler;

    private AuthenticationFailureHandler authenticationFailureHandler;

    private UserDetailsService userDetailsService;

    private SecurityProperties securityProperties;

    private StringRedisTemplate redisTemplate;

    @Autowired
    public void setRedisTemplate(StringRedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    @Autowired
    public void setSecurityProperties(SecurityProperties securityProperties) {
        this.securityProperties = securityProperties;
    }

    @Autowired
    public void setUserDetailsService(UserDetailsService userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

    @Autowired
    public void setAuthenticationFailureHandler(AuthenticationFailureHandler authenticationFailureHandler) {
        this.authenticationFailureHandler = authenticationFailureHandler;
    }

    @Autowired
    public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler authenticationSuccessHandler) {
        this.authenticationSuccessHandler = authenticationSuccessHandler;
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        MailAuthenticationFilter mailAuthenticationFilter = new MailAuthenticationFilter(securityProperties.getAuthentication().getMail().getProcessUrl());

        mailAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));
        mailAuthenticationFilter.setAuthenticationSuccessHandler(this.authenticationSuccessHandler);
        mailAuthenticationFilter.setAuthenticationFailureHandler(this.authenticationFailureHandler);

        MailAuthenticationProvider mailAuthenticationProvider = new MailAuthenticationProvider();
        mailAuthenticationProvider.setUserDetailsService(this.userDetailsService);
        mailAuthenticationProvider.setRedisTemplate(this.redisTemplate);

        // 加入自定义的Provider到security框架中
        http.authenticationProvider(mailAuthenticationProvider)
                .addFilterAfter(mailAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
}
